home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 7
/
Amiga Format AFCD07 (Dec 1996, Issue 91).iso
/
serious
/
shareware
/
programming
/
ixemul-complete
/
ixemul
/
library
/
group.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-18
|
8KB
|
385 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
* Portions Copyright (C) 1994 Rafael W. Luebbert
* Portions Copyright (C) 1996 Jeff Shepherd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* stubs for group-file access functions */
#define _KERNEL
#include "ixemul.h"
#include "kprintf.h"
#include <stdlib.h>
#include <grp.h>
#include <stdio.h>
#include "multiuser.h"
#include <amitcp/usergroup.h>
static int grscan(), start_gr();
#define MAXGRP 200
#define MAXLINELENGTH 1024
int getgroups(int gidsetlen, int *gidset)
{
/* parameter check */
if (gidset == NULL || gidsetlen < 0)
{
errno = EFAULT;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
if (gidsetlen == 0)
{
errno = EINVAL;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
if (muBase)
{
/* muFS detected */
UWORD *Grps;
int i;
/* get the information */
struct muExtOwner *me = muGetTaskExtOwner (NULL);
if (me == NULL)
{
*gidset = 0;
return 1; /* nobody */
}
/* store primary group */
gidset[0] = me->gid;
gidset++;
gidsetlen--;
/* ensure enough place */
if (gidsetlen < me->NumSecGroups)
{
errno = EINVAL;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
/* slow, but have to copy from UWORD[] --> int[] */
Grps = muSecGroups (me);
for (i = me->NumSecGroups; i >= 0; i--)
gidset[i] = Grps[i];
/* clean up */
i = me->NumSecGroups + 1;
muFreeExtOwner (me);
return i;
}
if (u.u_ixnetbase)
return netcall(NET_getgroups, gidsetlen, gidset);
/* we return 1 group, group 0 (you really ARE root on the amiga:-)) */
if (gidsetlen >= 1)
{
*gidset = 0;
return 1;
}
errno = EINVAL;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
static struct group *
GroupInfo2grp (struct muGroupInfo *GI, struct muUserInfo *UI)
{
static char *members[] = { NULL };
struct group *grp = &u.u_group;
if (GI)
{
grp->gr_name = GI->GroupID;
grp->gr_passwd = "*";
grp->gr_gid = GI->gid;
grp->gr_mem = members; /* much work has to be done on this */
return grp;
}
return NULL;
}
struct group *getgrgid (gid_t gid)
{
int rval;
if (muBase)
{
/* active multiuser */
struct muGroupInfo *GI = u.u_GroupInfo;
struct muUserInfo *UI = u.u_UserInfo;
GI->gid = gid;
GI = muGetGroupInfo (GI, muKeyType_gid);
return GroupInfo2grp (GI, UI); /* handles errors */
}
if (u.u_ixnetbase)
return (struct group *)netcall(NET_getgrgid, gid);
if (!start_gr())
return(NULL);
rval = grscan(1, gid, NULL);
if (!u.u_grp_stayopen)
endgrent();
return (rval ? &u.u_group : NULL);
}
struct group *getgrnam (const char *name)
{
int rval;
if (muBase)
{
/* active multiuser */
struct muGroupInfo *GI = u.u_GroupInfo;
struct muUserInfo *UI = u.u_UserInfo;
/*
* some validation checks
*/
if (name == NULL)
return NULL;
if ((muGROUPIDSIZE - 1) < strlen (name))
return NULL;
strcpy (GI->GroupID, name);
GI = muGetGroupInfo (GI, muKeyType_GroupID);
return GroupInfo2grp (GI, UI); /* handles errors */
}
if (u.u_ixnetbase)
return (struct group *)netcall(NET_getgrnam, name);
if (!start_gr())
return NULL;
rval = grscan(1, 0, name);
if (!u.u_grp_stayopen)
endgrent();
return (rval ? &u.u_group : NULL);
}
gid_t
getgid (void)
{
if (muBase)
return (muGetTaskOwner(NULL) & muMASK_GID);
if (u.u_ixnetbase)
return netcall(NET_getgid);
return 0;
}
gid_t
getegid (void)
{
if (muBase == NULL && u.u_ixnetbase)
return netcall(NET_getegid);
return getgid ();
}
struct group *
getgrent(void)
{
if (muBase)
{
/* active multiuser */
struct muGroupInfo *GI = u.u_fileGroupInfo;
struct muUserInfo *UI = u.u_UserInfo;
GI = muGetGroupInfo (GI, u.u_groupfileopen ? muKeyType_Next : muKeyType_First);
u.u_groupfileopen = TRUE;
return GroupInfo2grp (GI, UI); /* handles errors */
}
if (u.u_ixnetbase)
return (struct group *)netcall(NET_getgrent);
if ((!u.u_grp_fp && !start_gr()) || !grscan(0, 0, NULL))
return NULL;
return &u.u_group;
}
static int
start_gr(void)
{
if (u.u_grp_fp) {
syscall(SYS_rewind, u.u_grp_fp);
return 1;
}
return ((u.u_grp_fp = (FILE *)syscall(SYS_fopen, _PATH_GROUP, "r")) ? 1 : 0);
}
int
setgrent(void)
{
if (muBase || !u.u_ixnetbase)
return setgroupent(0);
return netcall(NET_setgrent);
}
int
setgroupent(int stayopen)
{
if (muBase)
{
u.u_groupfileopen = FALSE;
return 1;
}
if (u.u_ixnetbase)
return netcall(NET_setgroupent, stayopen);
if (!start_gr())
return 0;
u.u_grp_stayopen = stayopen;
return 1;
}
void
endgrent(void)
{
if (muBase)
{
setgroupent(0);
return;
}
if (u.u_ixnetbase) {
netcall(NET_endgrent);
return;
}
if (u.u_grp_fp) {
syscall(SYS_fclose, u.u_grp_fp);
u.u_grp_fp = NULL;
}
}
static int
grscan(int search, int gid, char *name)
{
register char *cp, **m;
char *bp;
char *fgets(), *strsep(), *index();
if (u.u_grp_line == NULL)
u.u_grp_line = malloc(MAXLINELENGTH);
if (u.u_members == NULL)
u.u_members = malloc(MAXGRP * sizeof(char *));
if (u.u_grp_line == NULL || u.u_members == NULL)
{
errno = ENOMEM;
return 0;
}
for (;;) {
if (!syscall(SYS_fgets, u.u_grp_line, MAXLINELENGTH, u.u_grp_fp))
return 0;
bp = u.u_grp_line;
/* skip lines that are too big */
if (!index(u.u_grp_line, '\n')) {
int ch;
while ((ch = getc(u.u_grp_fp)) != '\n' && ch != EOF) ;
continue;
}
u.u_group.gr_name = strsep(&bp, ":\n");
if (search && name && strcmp(u.u_group.gr_name, name))
continue;
u.u_group.gr_passwd = strsep(&bp, ":\n");
if (!(cp = strsep(&bp, ":\n")))
continue;
u.u_group.gr_gid = atoi(cp);
if (search && name == NULL && u.u_group.gr_gid != gid)
continue;
for (m = u.u_group.gr_mem = u.u_members;; ++m) {
if (m == &u.u_members[MAXGRP - 1]) {
*m = NULL;
break;
}
if ((*m = strsep(&bp, ", \n")) == NULL)
break;
}
return 1;
}
/* NOTREACHED */
}
int
setgroups (int ngroups, const int *gidset)
{
if (u.u_ixnetbase && !muBase)
return netcall(NET_setgroups, ngroups, gidset);
return (ngroups >= 1) ? 0 : -1;
}
int
initgroups (const char *name, int basegid)
{
if (u.u_ixnetbase && !muBase)
return netcall(NET_initgroups, name, basegid);
return 0;
}
int
setgid (gid_t gid)
{
if (u.u_ixnetbase && !muBase)
return netcall(NET_setgid, gid);
/* just always succeed... */
return 0;
}
int
setegid (gid_t gid)
{
if (u.u_ixnetbase && !muBase)
return netcall(NET_setegid, gid);
/* just always succeed... */
return 0;
}
int
setregid (int rgid, int egid)
{
if (u.u_ixnetbase && !muBase)
return netcall(NET_setregid, rgid, egid);
/* just always succeed... */
return 0;
}